import { App, Button, Modal, Segmented } from 'antd';
import { customAlphabet } from 'nanoid';
import React, { useCallback, useMemo, useState } from 'react';

import { SvgIcon } from '@/components/icon';
import QuestionTip from '@/components/tooltip/QuestionTip';
import { t } from '@/locales/i18n';
import { VariableItemType } from '@/types/app/type';
import { VariableInputEnum, variableMap, WorkflowIOValueTypeEnum } from '@/types/workflow/constant';
import { UserInputFormItemType } from '@/types/workflow/template/system/interactive/type';
import { formatEditorVariablePickerIcon } from '@/types/workflow/utils';

import InputTypeConfig from '../NodePluginIO/InputTypeConfig';

import VariableItem from './VariableItem';

const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6);

export const defaultVariable: VariableItemType = {
  id: nanoid(),
  key: '',
  label: '',
  type: VariableInputEnum.input,
  description: '',
  required: true,
  valueType: WorkflowIOValueTypeEnum.string,
};

type InputItemType = VariableItemType & {
  list: { label: string; value: string }[];
};

export const addVariable = () => {
  const newVariable = { ...defaultVariable, key: '', id: '', list: [{ value: '', label: '' }] };
  return newVariable;
};

function VariableEdit({
  variables = [],
  onChange,
  headerClassName,
}: {
  variables?: VariableItemType[];
  onChange: (data: VariableItemType[]) => void;
  headerClassName?: string;
}) {
  const { message } = App.useApp();
  const [modalVisible, setModalVisible] = useState(false);
  const [data, setData] = useState<VariableItemType>(addVariable());

  const value = data;
  // 使用 Form.useWatch 监听字段变化
  const { type } = data;

  const inputTypeList = useMemo(
    () =>
      Object.values(variableMap)
        .filter((item) => item.value !== VariableInputEnum.textarea)
        .map((item) => ({
          label: t(item.label as any),
          value: item.value,
          defaultValueType: item.defaultValueType,
          description: item.description ? t(item.description as any) : '',
        })),
    [],
  );

  const defaultValueType = useMemo(() => {
    const item = inputTypeList.find((item) => item.value === type);
    console.log('item', item);
    return item?.defaultValueType;
  }, [inputTypeList, type]);

  const formatVariables = useMemo(() => {
    const results = formatEditorVariablePickerIcon(variables);
    return results.map<VariableItemType & { icon?: string }>((item) => {
      const variable = variables.find((variable) => variable.key === item.key)!;
      return {
        ...variable,
        icon: item.icon,
      };
    });
  }, [variables]);

  const onSubmitSuccess = (value: VariableItemType, action: 'confirm' | 'continue') => {
    const inputValue = value as InputItemType;
    inputValue.label = inputValue?.label?.trim();
    inputValue.key = inputValue?.key?.trim();
    if (inputValue.key === '') {
      message.warning('参数名是必须的');
      return;
    }
    if (inputValue.label === '') {
      message.warning('显示名称是必须的');
      return;
    }
    const existingVariable = variables.find(
      (item) => item.key === inputValue.key && item.id !== inputValue.id,
    );

    if (existingVariable) {
      message.warning(t('core.module.variable.key already exists'));
      return;
    }

    inputValue.enums = inputValue.list || [];

    if (inputValue.type === VariableInputEnum.custom) {
      inputValue.required = false;
    }

    const onChangeVariable = [...variables];
    if (inputValue.id) {
      const index = variables.findIndex((item) => item.id === inputValue.id);
      onChangeVariable[index] = inputValue;
    } else {
      onChangeVariable.push({
        ...inputValue,
        id: nanoid(),
      });
    }

    if (action === 'confirm') {
      onChange(onChangeVariable);
      setData({
        ...addVariable(),
      });
      setModalVisible(false);
    } else if (action === 'continue') {
      onChange(onChangeVariable);
      message.success(t('common.Add Success'));
      setData({
        ...addVariable(),
      });
    }
  };

  const onSubmitError = useCallback(
    (e: any) => {
      const errorMessages = Object.values(e as Record<string, { message?: string }>).filter(
        (item): item is { message: string } => Boolean(item?.message),
      );
      if (errorMessages.length > 0) {
        message.warning(errorMessages[0].message);
      }
    },
    [message],
  );

  const handleEditVariable = (
    item: (VariableItemType | UserInputFormItemType) & { icon?: string },
  ) => {
    if ('id' in item) {
      const formattedItem = {
        ...item,
        list: item.enums || [],
      };
      console.log('edit item ', formattedItem);
      setData({ ...formattedItem });
      setModalVisible(true);
    }
  };

  const handleTypeChange = (value: VariableInputEnum) => {
    const values = data;
    const defaultValIsNumber = Number.isNaN(Number(values.defaultValue)) === false;
    const defaultValueType = inputTypeList
      .flat()
      .find((item) => item.value === value)?.defaultValueType;
    if (
      value === VariableInputEnum.select ||
      (value === VariableInputEnum.numberInput && !defaultValIsNumber)
    ) {
      setData((prev) => {
        return {
          ...prev,
          defaultValue: '',
        };
      });
    }

    // 判断value如果是time，则判断value.valueType是否为time，date,datetime, 否则默认设置为time
    if (value === VariableInputEnum.time) {
      if (
        values.valueType !== undefined &&
        [
          WorkflowIOValueTypeEnum.time,
          WorkflowIOValueTypeEnum.date,
          WorkflowIOValueTypeEnum.datetime,
        ].includes(values.valueType)
      ) {
        setData((prev) => {
          return { ...prev, valueType: values.valueType };
        });
      } else {
        setData((prev) => {
          return { ...prev, valueType: WorkflowIOValueTypeEnum.time };
        });
      }
    }

    setData((prev) => {
      return { ...prev, type: value, valueType: defaultValueType as WorkflowIOValueTypeEnum };
    });
  };

  const handleFinish = (values: InputItemType) => {
    onSubmitSuccess(values, 'confirm');
  };

  const resetData = () => {
    setData({
      ...addVariable(),
    });
  };

  return (
    <div className="h-full">
      <div className={`flex ${headerClassName} ${variables.length > 0 ? 'mb-2' : ''}`}>
        <div className="flex items-center gap-2">
          <span>{t('core.module.Variable')}</span>
          <QuestionTip title={t('core.app.tip.variableTip')} />
        </div>
        <Button
          className="ml-auto"
          icon={<SvgIcon icon="ri--add-fill" color="var(--text-4)" size={16} />}
          type="text"
          onClick={() => {
            const variable = addVariable();
            setData({ ...variable });
            setModalVisible(true);
          }}
        />
      </div>

      <div className="flex flex-col gap-2">
        {formatVariables.map((item) => (
          <VariableItem
            key={item.id}
            variable={item}
            handleEditVariable={handleEditVariable}
            handleDeleteVariable={(item) => {
              if ('id' in item) {
                onChange(variables.filter((variable) => variable.id !== item.id));
              }
            }}
          />
        ))}
      </div>

      <Modal
        title={t('core.module.Variable Setting')}
        open={modalVisible}
        onCancel={() => {
          resetData();
          setModalVisible(false);
        }}
        style={{ maxWidth: 800, minWidth: '800px' }}
        footer={null}
        centered
        destroyOnHidden
      >
        <div className="flex flex-col gap-2 p-2">
          <Segmented
            block
            onChange={(value) => {
              handleTypeChange(value as VariableInputEnum);
            }}
            className="custom-segmented h-11"
            options={inputTypeList}
            value={type}
          />
          <InputTypeConfig
            data={data}
            setData={setData}
            type="variable"
            isEdit={!!value.id}
            inputType={type}
            defaultValueType={defaultValueType}
            onClose={() => {
              resetData();
              setModalVisible(false);
            }}
            onSubmitSuccess={onSubmitSuccess}
            onSubmitError={onSubmitError}
          />
        </div>
      </Modal>
    </div>
  );
}

export default React.memo(VariableEdit);
